home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / TextStyles.C < prev    next >
C/C++ Source or Header  |  1992-08-24  |  12KB  |  587 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "TextStyles.h"
  6.  
  7. #include "Class.h"
  8. #include "ObjectTable.h"
  9. #include "Math.h"
  10.  
  11. //---- ParaManager ------------------------------------------------------
  12.  
  13. SmartParaStyles gParaStyles;
  14.  
  15. NewMetaImpl(ParaStyleManager,OrdCollection, (TP(gParaStyles)));
  16.  
  17. ParaStyleManager::ParaStyleManager() : OrdCollection(cContainerInitCap)
  18. }
  19.  
  20. ParaStyleManager::~ParaStyleManager()
  21. {
  22.     Iter next(this);
  23.     register ParaStyle *pp;
  24.     while (pp= (ParaStyle*) next()) {
  25.     // sp->Object::~Object();
  26.     ObjectTable::Remove(pp);
  27.     delete (void*) pp;
  28.     }
  29. }
  30.  
  31. ParaStyle *ParaStyleManager::MakeParaStyle(ParaDesc &p)
  32. {
  33.     Iter next(this);
  34.     ParaStyle *pp;
  35.     while (pp= (ParaStyle*)next()) {
  36.     if (
  37.         (pp->p.alignment == p.alignment) 
  38.         && (pp->p.rightIndent == p.rightIndent) 
  39.         && (pp->p.leftIndent == p.leftIndent) 
  40.         && (pp->p.firstIndent == p.firstIndent)
  41.         && (pp->p.spacing == p.spacing)
  42.         && (pp->p.spaceBefore == p.spaceBefore)
  43.         && (pp->p.spaceAfter == p.spaceAfter)
  44.         && (pp->p.flags == p.flags)
  45.         && (pp->p.tabs.IsEqual(p.tabs))
  46.     )
  47.         return pp;
  48.     }
  49.     pp= new ParaStyle(0, p);
  50.     Add(pp);
  51.     return pp;
  52. }
  53.  
  54. ParaStyle *ParaStyleManager::ChangeProperty(
  55.     ParaStyle *pp, TxtParaProp mode, const ParaDesc &np
  56. )
  57. {
  58.     ParaDesc pd;
  59.     pp->CopyProperties(pd);
  60.     
  61.     if ((mode & eTxtPAlign) == eTxtPAlign)
  62.     pd.alignment= np.alignment;
  63.     if ((mode & eTxtPLeft) == eTxtPLeft)
  64.     pd.leftIndent= np.leftIndent;
  65.     if ((mode & eTxtPRight) == eTxtPRight)
  66.     pd.rightIndent= np.rightIndent;
  67.     if ((mode & eTxtPFirstIndent) == eTxtPFirstIndent)
  68.     pd.firstIndent= np.firstIndent;
  69.     if ((mode & eTxtPSpacing) == eTxtPSpacing)
  70.     pd.spacing= np.spacing;
  71.     if ((mode & eTxtPSpaceBefore) == eTxtPSpaceBefore)
  72.     pd.spaceBefore= np.spaceBefore;
  73.     if ((mode & eTxtPSpaceAfter) == eTxtPSpaceAfter)
  74.     pd.spaceAfter= np.spaceAfter;
  75.     if ((mode & eTxtPAddTab) == eTxtPAddTab)
  76.     pd.tabs.Add(np.tabs.stops[0].x, eTxtTLeft);
  77.     if ((mode & eTxtPAddTabR) == eTxtPAddTabR)
  78.     pd.tabs.Add(np.tabs.stops[0].x, eTxtTRight);
  79.     if ((mode & eTxtPAddTabC) == eTxtPAddTabC)
  80.     pd.tabs.Add(np.tabs.stops[0].x, eTxtTCenter);
  81.     if ((mode & eTxtPAddTabD) == eTxtPAddTabD)
  82.     pd.tabs.Add(np.tabs.stops[0].x, eTxtTDecimal);
  83.     if ((mode & eTxtPRemoveTab) == eTxtPRemoveTab)
  84.     pd.tabs.Remove(np.tabs.stops[0].x);
  85.     if ((mode & eTxtPRemoveTab) == eTxtPRemoveTab)
  86.     pd.tabs.Remove(np.tabs.stops[0].x);
  87.     if ((mode & eTxtPReplaceTabs) == eTxtPReplaceTabs)
  88.     pd.tabs= np.tabs;
  89.     if ((mode & eTxtPNoBreak) == eTxtPNoBreak) {
  90.     if (TESTBIT(np.flags, (int)eTxtPFlagNoBreak))
  91.         SETBIT(pd.flags, (int)eTxtPFlagNoBreak);
  92.     else
  93.         CLRBIT(pd.flags, (int)eTxtPFlagNoBreak);
  94.     }
  95.     if ((mode & eTxtPKeepNext) == eTxtPKeepNext) {
  96.     if (TESTBIT(np.flags, (int)eTxtPFlagKeep))
  97.         SETBIT(pd.flags, (int)eTxtPFlagKeep);
  98.     else
  99.         CLRBIT(pd.flags, (int)eTxtPFlagKeep);
  100.     }
  101.     return MakeParaStyle(pd);
  102. }
  103.  
  104. //---- SmartParaStyles ------------------------------------------------------
  105.  
  106. ParaStyleManager *SmartParaStyles::make()
  107. {
  108.     if (pm)
  109.     return pm;
  110.     
  111.     pm= new ParaStyleManager;
  112.     return pm;
  113. }
  114.  
  115. //------ ParaDesc -----------------------------------------------------------
  116.  
  117. void ParaDesc::SetProperty(TxtParaProp what, int value)
  118. {
  119.     switch (what) {
  120.     case eTxtPAlign:
  121.     alignment= (TxtParaAlign)value;
  122.     break;
  123.     case eTxtPLeft: 
  124.     leftIndent= value;
  125.     break;
  126.     case eTxtPRight: 
  127.     rightIndent= value;      
  128.     break;
  129.     case eTxtPFirstIndent: 
  130.     firstIndent= value;
  131.     break;
  132.     case eTxtPSpacing:
  133.     spacing= value; 
  134.     break;
  135.     case eTxtPSpaceBefore:
  136.     spaceBefore= value;
  137.     break;
  138.     case eTxtPSpaceAfter:
  139.     spaceAfter= value;
  140.     break; 
  141.     case eTxtPAddTab:
  142.     tabs.Add(value, eTxtTLeft);
  143.     break;
  144.     case eTxtPAddTabR:
  145.     tabs.Add(value, eTxtTRight);
  146.     break;
  147.     case eTxtPAddTabC:
  148.     tabs.Add(value, eTxtTCenter);
  149.     break;
  150.     case eTxtPAddTabD:
  151.     tabs.Add(value, eTxtTDecimal);
  152.     break;
  153.     case eTxtPEmptyTabs:
  154.     tabs.ntabs= 0;
  155.     break;
  156.     case eTxtPNoBreak:
  157.     if (value)
  158.         SETBIT(flags, (int)eTxtPFlagNoBreak);
  159.     else
  160.         CLRBIT(flags, (int)eTxtPFlagNoBreak);
  161.     break;
  162.     case eTxtPKeepNext:
  163.     if (value)
  164.         SETBIT(flags, (int)eTxtPFlagKeep);
  165.     else
  166.         CLRBIT(flags, (int)eTxtPFlagKeep);
  167.     break;
  168.     }
  169. }
  170.  
  171. bool ParaDesc::TestFlag(TxtParaFlags f)
  172. {
  173.     return TESTBIT(flags, (int)f);
  174. }
  175.  
  176. //------ ParaStyle ----------------------------------------------------------
  177.  
  178. NewMetaImpl(ParaStyle,Object, (T(p.rightIndent), T(p.leftIndent),
  179.              T(p.firstIndent), T(p.spacing),
  180.              T(p.spaceBefore), T(p.spaceAfter), TX(p.flags)));
  181.  
  182. ParaStyle::ParaStyle(int, ParaDesc &pp)
  183. {
  184.     p= pp;
  185. }
  186.  
  187. ParaStyle* new_ParaStyle(
  188.     TxtParaAlign a, int ri, int li, int fi, 
  189.     int sp, int sb, int sa, 
  190.     int f, ParaTabs *tabs
  191. )
  192. {
  193.     ParaDesc p;
  194.     p.flags= f;
  195.     p.alignment= a;
  196.     p.rightIndent= ri;
  197.     p.leftIndent= li;
  198.     p.firstIndent= fi;
  199.     p.spacing= Math::Max(0, sp);
  200.     p.spaceBefore= Math::Max(0, sb);
  201.     p.spaceAfter= Math::Max(0, sa);
  202.     if (tabs)
  203.     p.tabs.Copy(*tabs);
  204.     return gParaStyles->MakeParaStyle(p);
  205. }
  206.  
  207. ParaStyle* new_ParaStyle(ParaDesc &pp)
  208. {
  209.     return gParaStyles->MakeParaStyle(pp);
  210. }
  211.  
  212. ParaStyle::~ParaStyle()
  213. {
  214.     this= 0;
  215. }
  216.  
  217. bool ParaStyle::IsEqual (Object *op)
  218. {
  219.     return op == this;
  220. }
  221.  
  222. OStream &ParaStyle::PrintOn(OStream &s)
  223. {
  224.     return s << p.alignment SP 
  225.          << p.rightIndent SP << p.leftIndent SP << p.firstIndent SP 
  226.          << p.spacing SP << p.spaceBefore SP << p.spaceAfter SP
  227.          << p.tabs SP << p.flags NL;
  228. }
  229.  
  230. Object *ParaStyle::ReadAndMap(IStream &s)
  231. {
  232.     ParaDesc pp;
  233.     s >> Enum(pp.alignment) 
  234.       >> pp.rightIndent >> pp.leftIndent >> pp.firstIndent
  235.       >> pp.spacing >> pp.spaceBefore >> pp.spaceAfter >> pp.tabs >> pp.flags;
  236.     return new_ParaStyle(
  237.     pp.alignment, pp.rightIndent, pp.leftIndent,
  238.     pp.firstIndent, pp.spacing, pp.spaceBefore, pp.spaceAfter,
  239.     pp.flags, &pp.tabs
  240.     );
  241. }
  242.  
  243. Object *ParaStyle::deepclone()
  244. {
  245.     return this;
  246. }
  247.     
  248. void ParaStyle::CopyProperties(ParaDesc &pp)
  249. {
  250.     pp= p;
  251. }
  252.                      
  253. const ParaTabs &ParaStyle::GetTabs()
  254. {
  255.     return p.tabs;
  256. }
  257.  
  258. int ParaStyle::GetProperty(TxtParaProp what)
  259. {   
  260.     int val;
  261.     switch (what) {
  262.     case eTxtPAlign:
  263.     val= (TxtParaAlign)p.alignment;
  264.     break;
  265.     case eTxtPLeft: 
  266.     val= p.leftIndent;      
  267.     break;
  268.     case eTxtPRight: 
  269.     val= p.rightIndent;      
  270.     break;
  271.     case eTxtPFirstIndent: 
  272.     val= p.firstIndent;
  273.     break;
  274.     case eTxtPSpacing:
  275.     val= p.spacing; 
  276.     break;
  277.     case eTxtPSpaceBefore:
  278.     val= p.spaceBefore;
  279.     break;
  280.     case eTxtPSpaceAfter:
  281.     val= p.spaceAfter;
  282.     break; 
  283.     case eTxtPNoBreak:
  284.     val= TESTBIT(p.flags, (int)eTxtPFlagNoBreak);
  285.     break;
  286.     case eTxtPKeepNext:
  287.     val= TESTBIT(p.flags, (int)eTxtPFlagKeep);
  288.     break;
  289.     default:
  290.     val= -1;
  291.     }
  292.     return val;
  293. }
  294.  
  295. //---- ParaTabs ---------------------------------------------------------------
  296.  
  297. const int cTabCapacity= 6;
  298.  
  299. ParaTabs::ParaTabs()
  300. {
  301.     size= 0;
  302.     ntabs= 0;
  303.     stops= 0;
  304. }
  305.  
  306. ParaTabs::~ParaTabs()
  307. {
  308.     if (size != 0)
  309.     delete stops;
  310. }
  311.  
  312. void ParaTabs::operator= (const ParaTabs &pt)
  313. {
  314.     if (&pt == this)
  315.     return;
  316.     SafeDelete(stops);
  317.     Copy(pt);
  318. }
  319.  
  320. void ParaTabs::Copy(const ParaTabs &t)
  321. {
  322.     ntabs= t.ntabs;
  323.     if (ntabs == 0) {
  324.     stops= 0;
  325.     size= 0;
  326.     } else {
  327.     size= t.size;
  328.     stops= new TabStop[size];
  329.     for(int i= 0; i < ntabs; i++)
  330.         stops[i]= t.stops[i];
  331.     }    
  332. }
  333.  
  334. bool ParaTabs::IsEqual(ParaTabs &t)
  335. {
  336.     if (t.ntabs != ntabs)
  337.     return FALSE;
  338.     for (int i= 0; i < ntabs; i++)
  339.     if (stops[i].kind != t.stops[i].kind || stops[i].x != t.stops[i].x)
  340.         return FALSE;
  341.     return TRUE;
  342. }
  343.  
  344. void ParaTabs::Add(int x, TxtTabStop kind)
  345. {
  346.     for (int i= 0; i < ntabs; i++) {
  347.     if(stops[i].x == x) {
  348.         stops[i].kind= kind;
  349.         return;
  350.     }
  351.     else if (stops[i].x > x)
  352.         break;
  353.     }
  354.     if (size == ntabs) {
  355.     if (size == 0)
  356.         stops= new TabStop[size= cTabCapacity];
  357.     else {
  358.         stops= (TabStop*)Realloc(stops, 2*size*sizeof(TabStop));
  359.         size= 2*size;
  360.     }
  361.     }
  362.     for(int j= ntabs-1; j >= i; j--)
  363.     stops[j+1]= stops[j];
  364.     stops[i].x= x;
  365.     stops[i].kind= kind;
  366.     ntabs++;
  367. }
  368.  
  369. void ParaTabs::Remove(int ix)
  370. {
  371.     if (ix >= ntabs)
  372.     return;
  373.     for (int j= ix; j < size-1; j++)
  374.     stops[j]= stops[j+1];
  375.     ntabs--;
  376. }
  377.     
  378. void ParaTabs::Move(int ix, int dx)
  379. {
  380.     if (ix >= ntabs)
  381.     return;
  382.     TabStop t;
  383.     t.x= stops[ix].x + dx;
  384.     t.kind= stops[ix].kind;
  385.     Remove(ix);
  386.     Add(t.x, t.kind);
  387. }
  388.  
  389. OStream& operator<< (OStream& s, ParaTabs &p)
  390. {
  391.     s << p.ntabs SP;
  392.     for (int i= 0; i < p.ntabs; i++)
  393.     s << p.stops[i].x SP << p.stops[i].kind SP;
  394.     return s;
  395. }
  396.  
  397. IStream& operator>> (IStream& s, ParaTabs &p)
  398. {
  399.     s >> p.ntabs;
  400.     p.stops= new TabStop[p.size= Math::Max(p.ntabs, cTabCapacity)];
  401.     for (int i= 0; i < p.ntabs; i++)
  402.     s >> p.stops[i].x >> Enum(p.stops[i].kind);
  403.     return s; 
  404. }
  405.  
  406. //------ CharStyleSpec --------------------------------------------------------
  407.  
  408. CharStyleSpec::CharStyleSpec()
  409. {
  410.     font= eFontHelvetica;
  411.     face= eFacePlain;
  412.     size= 12;
  413.     ink= ePatBlack;
  414.     xor= TRUE;
  415. }
  416.     
  417. CharStyleSpec::CharStyleSpec(Font *fp, Ink *c, bool mode)
  418.     font= fp->Fid();
  419.     face= fp->Face();
  420.     size= fp->Size();
  421.     ink= c;
  422.     xor= mode;
  423. }
  424.  
  425. CharStyleSpec::CharStyleSpec(GrFont ft, GrFace fc, int sz, Ink *c, bool mode)
  426.     font= ft; 
  427.     face= fc; 
  428.     size= sz; 
  429.     ink= c; 
  430.     xor= mode; 
  431. }
  432.  
  433. //------ CharDesc -----------------------------------------------------------
  434.  
  435. void CharDesc::GetFontProp(GrFont &fid, GrFace &face, int &size) 
  436. {
  437.     fid= fp->Fid();
  438.     face= fp->Face();
  439.     size= fp->Size();
  440. }
  441.  
  442. //------ CharStyleManager --------------------------------------------------
  443.  
  444. SmartCharStyles gCharStyles;
  445.  
  446. NewMetaImpl(CharStyleManager,OrdCollection, (TP(gCharStyles)));
  447.  
  448. CharStyleManager::CharStyleManager() : OrdCollection(cContainerInitCap)
  449. }
  450.  
  451. CharStyleManager::~CharStyleManager()
  452. {
  453.     Iter next(this);
  454.     register CharStyle *sp;
  455.     while (sp= (CharStyle*) next()) {
  456.     // sp->Object::~Object();
  457.     ObjectTable::Remove(sp);
  458.     delete (void*) sp;
  459.     }
  460. }
  461.  
  462. CharStyle *CharStyleManager::MakeCharStyle(CharDesc &cc)
  463. {
  464.     Iter next(this);
  465.     register CharStyle *sp;
  466.     while (sp= (CharStyle*)next()) {
  467.     if (
  468.         sp->c.fp == cc.fp && 
  469.         sp->c.ink == cc.ink
  470.     ) 
  471.         return sp;
  472.     }
  473.     sp= new CharStyle(0, cc);
  474.     Add(sp);
  475.     return sp;
  476. }
  477.  
  478. CharStyle *CharStyleManager::ChangeProperty(
  479.     CharStyle *cs, TxtCharProp mode, CharStyleSpec st
  480. )
  481. {
  482.     CharDesc cc;
  483.     GrFont fid;
  484.     GrFace face;
  485.     int    fsize;
  486.        
  487.     cs->GetProperties(cc);
  488.     cc.GetFontProp(fid, face, fsize);
  489.     if ((mode & eTxTPFont) == eTxTPFont)
  490.     fid= st.font;
  491.     if ((mode & eTxTPFace) == eTxTPFace)
  492.     if (st.face == eFacePlain)
  493.         face= st.face;
  494.     else {
  495.         if (st.xor == cStyleXorMode)
  496.         face= (GrFace)(face ^ st.face);
  497.         else
  498.         face= (GrFace)(face | st.face);
  499.     }
  500.     if ((mode & eTxtPSize) == eTxtPSize)
  501.     fsize= st.size;
  502.     if ((mode & eTxtPAddSize) == eTxtPAddSize)
  503.     fsize+= st.size;
  504.     if ((mode & eTxtPInk) == eTxtPInk)
  505.     cc.ink= st.ink;
  506.     cc.fp= new_Font(fid, fsize, face);
  507.     return MakeCharStyle(cc);
  508. }
  509.  
  510. CharStyle *CharStyleManager::Default()
  511. {
  512.     return new_CharStyle(gSysFont, ePatBlack);
  513. }
  514.  
  515. //---- SmartCharStyles ------------------------------------------------------
  516.  
  517. CharStyleManager *SmartCharStyles::make()
  518. {
  519.     if (cm)
  520.     return cm;
  521.     
  522.     cm= new CharStyleManager;
  523.     return cm;
  524. }
  525.  
  526. //------ CharStyle -----------------------------------------------------------
  527.  
  528. NewMetaImpl(CharStyle,Object, (TP(c.fp), TP(c.ink))); 
  529.  
  530. CharStyle::CharStyle(int, CharDesc &cc)
  531. {
  532.     c= cc;
  533. }
  534.  
  535. CharStyle *new_CharStyle(Font *f, Ink *c)
  536. {
  537.     CharDesc cc;
  538.     cc.fp= f;
  539.     cc.ink= c;
  540.     return gCharStyles->MakeCharStyle(cc);
  541. }
  542.  
  543. CharStyle *new_CharStyle(GrFont ft, GrFace fc, int size, Ink *ink)
  544. {
  545.     CharDesc cc;
  546.     cc.fp= new_Font(ft, size, fc);
  547.     cc.ink= ink;
  548.     return gCharStyles->MakeCharStyle(cc);
  549. }
  550.  
  551. CharStyle::~CharStyle()
  552. {
  553.     this= 0;
  554. }
  555.     
  556. OStream &CharStyle::PrintOn(OStream &s) 
  557. {    
  558.     return s << c.fp SP << c.ink NL;
  559. }
  560.  
  561. Object *CharStyle::ReadAndMap(IStream &s)
  562.     CharDesc cc;
  563.     s >> cc.fp >> cc.ink;
  564.     return new_CharStyle(cc.fp, cc.ink);
  565. }
  566.  
  567. bool CharStyle::IsEqual(Object *op)
  568. {
  569.     return op == this;
  570. }
  571.  
  572. void CharStyle::GetProperties(CharDesc &cc)
  573. {
  574.     cc.fp= c.fp;
  575.     cc.ink= c.ink;
  576. }
  577.  
  578. Object *CharStyle::deepclone()
  579. {
  580.     return this;
  581. }
  582.